www.gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFMovie.cpp

    // SWFMovie.cpp: implementation of the CSWFMovie class.
//
//////////////////////////////////////////////////////////////////////

#include "SWFMovie.h"


CSWFMovie::CSWFMovie()
{
	// Init .SWF file header struct
	strcpy((char*)m_SWFHeader.Signature, "FWS");
	m_SWFHeader.Version = SWF_FILE_VERSION;
	m_SWFHeader.FileLength = 0;
	RECT_F rectangle = {0, 0, SWF_MOVIE_WIDHT, SWF_MOVIE_HEIGHT};
	m_SWFMovieRectangle.SetRectangle(rectangle);
	m_SWFHeader.FrameRate = 0x0C00;
	m_SWFHeader.FrameCount = 0;

	// Init .SWF file descriptor
	m_SWFFile = NULL;

	// Init .SWF file stream
	m_SWFFileStream = NULL;
	m_SWFFileStreamLength = 0;
}

CSWFMovie::~CSWFMovie()
{
	if (m_SWFFileStream != NULL)
	{
		free(m_SWFFileStream);
		m_SWFFileStreamLength = NULL;
	}
}

BOOL CSWFMovie::OpenSWFFile(LPTSTR filename, SIZE_F movieSize, int frameRate)
{
	BOOL bResult = TRUE;

	if (m_SWFFile == NULL)
	{
		// Open new .SWF file
		m_SWFFile = fopen(filename, "wb");
		strcpy(m_SWFFileName, filename);

		if (m_SWFFile == NULL)
			bResult = FALSE;
		else
		{
			// Set movie info
			RECT_F rectangle = {0, 0, movieSize.cx, movieSize.cy};
			m_SWFMovieRectangle.SetRectangle(rectangle);
			m_SWFHeader.FrameRate = MAKEWORD(0, frameRate);
		}
	}
	else
		bResult = FALSE;

	return bResult;
}

void CSWFMovie::CloseSWFFile()
{
	// Close .SWF file
	if (m_SWFFile)
	{
		// Go to the beginning of the .SWF file
		fseek(m_SWFFile, 0, SEEK_SET);

		// Write SWF_FILE_HEADER struct to the file
		WriteSWFHeaderAndStream();

		// Go to the end of the .SWF file
		fseek(m_SWFFile, 0, SEEK_END);

		// Write End tag
		USHORT endTag = 0x0000;
		fwrite(&endTag, sizeof(USHORT), 1, m_SWFFile);
		
		fclose(m_SWFFile);
		m_SWFFile = NULL;
	}
}

void CSWFMovie::WriteSWFHeaderAndStream()
{
	// Check if file is opened
	if (m_SWFFile)
	{
		// Check if .SWF file is closing
		UCHAR* pBuffer = m_SWFMovieRectangle.BuildSWFStream();
		int numBytes = m_SWFMovieRectangle.GetSWFStreamLength();
			
		// Calculate total file size
		m_SWFHeader.FileLength = m_SWFFileStreamLength;
		m_SWFHeader.FileLength += sizeof(SWF_FILE_HEADER);			// .SWF file header size
		m_SWFHeader.FileLength += numBytes;							// Additional header size
		m_SWFHeader.FileLength += sizeof(USHORT);					// .SWF End tag size

		// Write .SWF file header
		fwrite(m_SWFHeader.Signature, sizeof(UCHAR), 3, m_SWFFile);
		fwrite(&m_SWFHeader.Version, sizeof(UCHAR), 1, m_SWFFile);
		fwrite(&m_SWFHeader.FileLength, sizeof(UINT), 1, m_SWFFile);
		fwrite(pBuffer, sizeof(UCHAR), numBytes, m_SWFFile);
		fwrite(&m_SWFHeader.FrameRate, sizeof(USHORT), 1, m_SWFFile);
		fwrite(&m_SWFHeader.FrameCount, sizeof(USHORT), 1, m_SWFFile);

		// Write .SWF file stream
		fwrite(m_SWFFileStream, sizeof(UCHAR), m_SWFFileStreamLength, m_SWFFile);
	}
}

void CSWFMovie::SetBackgroundColor(SWF_RGB bgColor)
{
	// SetBackgroundColor tag
	SWF_BGCOLOR bgColorTag;
	bgColorTag.Header.TagCodeAndLength = 9;
	bgColorTag.Header.TagCodeAndLength = (bgColorTag.Header.TagCodeAndLength << 6) | 3;
	memcpy(&bgColorTag.BackgroundColor, &bgColor, sizeof(SWF_RGB));

	// Modify total .SWF file size
	int newLength = m_SWFFileStreamLength + sizeof(SWF_BGCOLOR);

	// Write SetBackgroundColor tag
	if (m_SWFFileStreamLength == 0)
		m_SWFFileStream = (BYTE*)malloc(newLength);
	else
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &bgColorTag, sizeof(SWF_BGCOLOR));
	m_SWFFileStreamLength = newLength;
}

void CSWFMovie::SetFrameLabel(UCHAR* frameLabel)
{
	// FrameLabel tag
	SWF_RECORDHEADER_LONG FrameLabelTag;
	FrameLabelTag.TagCodeAndLength = (43 << 6) | 0x003F;
	int frameLabelLength = strlen((char*)frameLabel) + 1;
	FrameLabelTag.Length = frameLabelLength;

	// Modify total .SWF file size
	int newLength = m_SWFFileStreamLength + sizeof(SWF_RECORDHEADER_LONG) + frameLabelLength;

	// Write FrameLabel tag
	if (m_SWFFileStreamLength == 0)
		m_SWFFileStream = (BYTE*)malloc(newLength);
	else
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &FrameLabelTag, sizeof(SWF_RECORDHEADER_LONG));
	memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG), frameLabel, frameLabelLength);
	m_SWFFileStreamLength = newLength;
}

void CSWFMovie::ShowFrame()
{
	// ShowFrame tag
	USHORT showFrameTage = 0x0040;

	// Modify total .SWF file size
	int newLength = m_SWFFileStreamLength + sizeof(USHORT);

	// Write ShowFrame tag
	if (m_SWFFileStreamLength == 0)
		m_SWFFileStream = (BYTE*)malloc(newLength);
	else
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &showFrameTage, sizeof(USHORT));
	m_SWFFileStreamLength = newLength;

	// Increment frame counter
	m_SWFHeader.FrameCount++;
}

void CSWFMovie::TriggerAction(CSWFAction* pAction)
{
	// Write DoAction tag to .SWF stream
	if (pAction != NULL)
	{
		UCHAR* pBuffer = pAction->BuildSWFStream();

		// Modify total .SWF file size
		int newLength = m_SWFFileStreamLength + pAction->GetSWFStreamLength();

		// Write DefineShape tag
		if (m_SWFFileStreamLength == 0)
			m_SWFFileStream = (BYTE*)malloc(newLength);
		else
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pBuffer, pAction->GetSWFStreamLength());
		m_SWFFileStreamLength = newLength;
	}
}

void CSWFMovie::DefineObject(CSWFObject* pObject, int depth, bool bShow)
{
	if (pObject != NULL)
	{
		// Get sprite SWF stream
		UCHAR* pBuffer = pObject->BuildSWFStream();
		int objectLength = pObject->GetSWFStreamLength();

		int newLength = m_SWFFileStreamLength + objectLength;
		if (m_SWFFileStreamLength == 0)
			m_SWFFileStream = (BYTE*)malloc(newLength);
		else
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pBuffer, objectLength);
		m_SWFFileStreamLength = newLength;

		// Initial display object
		if ((bShow) && (pObject->m_ObjectType != SWF_OBJECT_TYPE_BITMAP))
			DisplayObject(pObject, depth, TRUE, NULL, -1);
	}
}

void CSWFMovie::AddObject(CSWFObject* pObject, int depth, SWF_COLOR_TRANSFORM* pColorTransform, int ratio, bool bInitialDisplay)
{
	if (pObject != NULL)
	{
		// Display object
		DisplayObject(pObject, depth, bInitialDisplay, pColorTransform, ratio);
	}
}

void CSWFMovie::UpdateObject(CSWFObject* pObject, int depth, SWF_COLOR_TRANSFORM* pColorTransform, int ratio)
{
	if (pObject != NULL)
	{
		// Display object
		DisplayObject(pObject, depth, FALSE, pColorTransform, ratio);
	}
}

void CSWFMovie::RemoveObject(int depth)
{
	// Format RemoveObject2 tag
	SWF_REMOVE_OBJECT2_TAG removeObjectTag;
	memset(&removeObjectTag, 0, sizeof(SWF_REMOVE_OBJECT2_TAG));
	removeObjectTag.Header.TagCodeAndLength = (28 << 6) | 0x003F;
	removeObjectTag.Header.Length = 2;
	removeObjectTag.Depth = depth;

	// Write RemoveObject2 tag
	int newLength = m_SWFFileStreamLength + (removeObjectTag.Header.Length-2) + sizeof(SWF_REMOVE_OBJECT2_TAG);
	if (m_SWFFileStreamLength == 0)
		m_SWFFileStream = (BYTE*)malloc(newLength);
	else
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &removeObjectTag, sizeof(SWF_REMOVE_OBJECT2_TAG));
	m_SWFFileStreamLength = newLength;
}

void CSWFMovie::DisplayObject(CSWFObject* pObject, int depth, bool bInitialDisplay, SWF_COLOR_TRANSFORM* pColorTransform, int ratio)
{
	if (pObject != NULL)
	{
		// Format PlaceObject2 tag
		SWF_PLACE_OBJECT_TAG placeObjectTag;
		memset(&placeObjectTag, 0, sizeof(SWF_PLACE_OBJECT_TAG));
		placeObjectTag.Header.TagCodeAndLength = (26 << 6) | 0x003F;
		placeObjectTag.Header.Length = 0;
		if (bInitialDisplay)
			placeObjectTag.CharacterID = pObject->m_ID;
		placeObjectTag.Depth = depth;
		if (bInitialDisplay)
			placeObjectTag.Flags = 0x06;
		else
			placeObjectTag.Flags = 0x05;
		if (pColorTransform != NULL)
			placeObjectTag.Flags |= 0x08;
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE)
			placeObjectTag.Flags |= 0x10;
		int nameLength = 0;
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE)
		{
			if (((CSWFSprite*)pObject)->m_Name != NULL)
			{
				nameLength = strlen((char*)((CSWFSprite*)pObject)->m_Name) + 1;
				placeObjectTag.Flags |= 0x20;
			}
		}

		// Get transformation matrix
		UCHAR* pTransformationMatrix = NULL;
		int transformationMatrixLength = 0;
		switch (pObject->m_ObjectType)
		{
			case SWF_OBJECT_TYPE_SHAPE:
			{
				pTransformationMatrix = ((CSWFShape*)pObject)->m_TransformationMatrix.BuildSWFStream();
				transformationMatrixLength = ((CSWFShape*)pObject)->m_TransformationMatrix.GetSWFStreamLength();
			}
			break;

			case SWF_OBJECT_TYPE_MORPH_SHAPE:
			{
				pTransformationMatrix = ((CSWFMorphShape*)pObject)->m_TransformationMatrix.BuildSWFStream();
				transformationMatrixLength = ((CSWFMorphShape*)pObject)->m_TransformationMatrix.GetSWFStreamLength();
			}
			break;

			case SWF_OBJECT_TYPE_BUTTON:
			{
				pTransformationMatrix = ((CSWFButton*)pObject)->m_TransformationMatrix.BuildSWFStream();
				transformationMatrixLength = ((CSWFButton*)pObject)->m_TransformationMatrix.GetSWFStreamLength();
			}
			break;

			case SWF_OBJECT_TYPE_SPRITE:
			{
				pTransformationMatrix = ((CSWFSprite*)pObject)->m_TransformationMatrix.BuildSWFStream();
				transformationMatrixLength = ((CSWFSprite*)pObject)->m_TransformationMatrix.GetSWFStreamLength();
			}
			break;
		}

		// Get color transformation
		CSWFColorTransform colorTranform(pColorTransform);
		UCHAR* pColorTransformBuffer = colorTranform.BuildSWFStream();
		int colorTransformLength = colorTranform.GetSWFStreamLength();

		// Calculate tag length
		placeObjectTag.Header.Length += sizeof(UCHAR);					// sizeof Flags
		placeObjectTag.Header.Length += sizeof(USHORT);					// sizeof Depth
		if (bInitialDisplay)
			placeObjectTag.Header.Length += sizeof(USHORT);				// sizeof CharacterID
		placeObjectTag.Header.Length += transformationMatrixLength;		// sizeof TransformationMatrix
		if (pColorTransform != NULL)
			placeObjectTag.Header.Length += colorTransformLength;		// sizeof ColorTransformation
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE)
			placeObjectTag.Header.Length += sizeof(USHORT);				// sizeof Ratio
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE)			// sizeof Name
		{
			if (nameLength != 0)
				placeObjectTag.Header.Length += strlen((char*)((CSWFSprite*)pObject)->m_Name) + 1;
		}

		// Write PlaceObject2 tag
		int newLength = m_SWFFileStreamLength + placeObjectTag.Header.Length + sizeof(SWF_RECORDHEADER_LONG);
		if (m_SWFFileStreamLength == 0)
			m_SWFFileStream = (BYTE*)malloc(newLength);
		else
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength);

		// Write PlaceObject2 tag
		newLength = m_SWFFileStreamLength + sizeof(SWF_RECORDHEADER_LONG) + sizeof(UCHAR) + sizeof(USHORT);
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, &placeObjectTag.Header, sizeof(SWF_RECORDHEADER_LONG));
		memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG), &placeObjectTag.Flags, sizeof(UCHAR));
		memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG)+sizeof(UCHAR), &placeObjectTag.Depth, sizeof(USHORT));
		m_SWFFileStreamLength = newLength;

		// Write CharacterID
		if (bInitialDisplay)
		{
			newLength = m_SWFFileStreamLength + sizeof(USHORT);
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, &placeObjectTag.CharacterID, sizeof(USHORT));
			m_SWFFileStreamLength = newLength;
		}

		// Write Matrix
		newLength = m_SWFFileStreamLength + transformationMatrixLength;
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pTransformationMatrix, transformationMatrixLength);
		m_SWFFileStreamLength = newLength;

		// Write ColorTransform
		if (pColorTransform != NULL)
		{
			newLength = m_SWFFileStreamLength + colorTransformLength;
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, pColorTransformBuffer, colorTransformLength);
			m_SWFFileStreamLength = newLength;
		}

		// Write Ratio
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE)
		{
			newLength = m_SWFFileStreamLength + sizeof(USHORT);
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, &ratio, sizeof(USHORT));
			m_SWFFileStreamLength = newLength;
		}

		// Write Name
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE)
		{
			if (nameLength != 0)
			{
				newLength = m_SWFFileStreamLength + nameLength;
				memcpy(m_SWFFileStream+m_SWFFileStreamLength, ((CSWFSprite*)pObject)->m_Name, nameLength);
				m_SWFFileStreamLength = newLength;
			}
		}
	}
}